function varargout = TLSfdataDlg(action,varargin)

% TL_SFDATA_DLG manages the user interface for SF Data objects in TargetLink.
%
% SYNTAX dlgInfo = TLSfdataDlg('GetDlgInfo');
%   gets dialog info of SF Data objects in TargetLink
%
%   INPUT ARGUMENTS
%   -/-      
%
%   OUTPUT ARGUMENTS
%   dlgInfo     dialog information contains pageNames etc.
%
% SYNTAX [sheetDims, ctrlPos] = ...
%           TLSfdataDlg('CtrlPositions', pageName, commonGeom, dlgInfo, sheetDims);
%   calculates the control positions of all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   commonGeom      common geometry data
%   dlgInfo         dialog information contains pageNames etc.
%   sheetDims       dimension of sheet
%
%   OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% SYNTAX dlgdata = TLSfdataDlg('Create', pageName, dlgfig, dlgdata);
%   creates all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX [dlgdata,bModified] = TLSfdataDlg('Manage', pageName, dlgfig, dlgdata, pageAction);
%   manages all actions of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageAction      modified control of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%   bModified       flag = 1, if dialog data are modified, =0 otherwise
%
% SYNTAX dlgdata = TLSfdataDlg('Update', dlgfig, dlgdata, pageNum);
%   updates all controls of dialog page: <pageNum>
%
%   INPUT ARGUMENTS
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageNum         number of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX TLSfdataDlg('Apply', dlgfig, dlgdata);
%   writes current blockdata to block and DD
%
%   INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
%   OUTPUT ARGUMENTS
%   - / -


% Author(s): C.Witte, D. Andoleit, T. Pietzsch
% $RCSfile: TLSfdataDlg.m $
% $ProjectName: e:/ARC/Components/HostSW/SimulinkBlocksets/TLBlocksets/StateflowBlockset/Sources/MSrc/project.pj $
% $Revision: 1.7 $
% $Date: 2011/10/04 06:23:41MESZ $
%
% Copyright ?2011 dSPACE GmbH. All rights reserved.


switch action

    case 'GetDlgInfo'
        hSFObject = varargin{1};
        data = get_tlcg_data(hSFObject);
        
        dlgInfo = tl_get_dlginfodefaults('tlsim');
        titleName = tl_classify_sfobject(hSFObject);
        pathinfo = tl_pathinfo(hSFObject);
        dlgInfo.title = sprintf('TargetLink %s: %s', titleName, pathinfo.shortDisplayName);
        dlgInfo.bPlotSignal          = isfield(data,'loggingmode');
        dlgInfo.bAutoscaling         = isfield(data,'autoscalingmode');
        dlgInfo.bRTOS                = isfield(data,'message');
        dlgInfo.bAccessor            = isfield(data,'accessor');
        dlgInfo.bShowBlock           = 1;
        dlgInfo.bDateLabel           = 0;
        dlgInfo.bLimits              = isfield(data,'checkmin');
        dlgInfo.bInheritance         = isfield(data,'inheritscaling');
        dlgInfo.bAddress             = isfield(data,'address');
        dlgInfo.bValue               = isfield(data,'value');
        dlgInfo.bCreateInputVariable = isfield(data,'createinputvariable');
        dlgInfo.bHeadRooms           = isfield(data,'headroomunit');
        
        % check whether the object is inside a chart, not in a mashine
        sr = sfroot;
        sfObj = sr.find('Id', hSFObject);
        dlgInfo.bEditCode            = ~sfObj.up.isa('BlockDiagram');
        
        % view code only for outputs
        dlgInfo.bViewCode            = 0; %(sf('get',hSFObject,'.scope') == 2);
        
        dlgInfo.pageNames = {
                'Variable'};
        if dlgInfo.bPlotSignal && dlgInfo.bAutoscaling
           dlgInfo.pageNames{end+1} = 'Logging & Autoscaling';
        end
        if dlgInfo.bPlotSignal && ~dlgInfo.bAutoscaling
           dlgInfo.pageNames{end+1} = 'Logging';
        end
        if ~dlgInfo.bPlotSignal && dlgInfo.bAutoscaling
           dlgInfo.pageNames{end+1} = 'Autoscaling';
        end
        if dlgInfo.bRTOS
            dlgInfo.pageNames{end+1} = 'RTOS';
        end    
        varargout{1} = dlgInfo;
        varargout{2} = data;

    case 'CtrlPositions'
        pageName     = varargin{1};
        commonGeom   = varargin{2};
        dlgInfo      = varargin{3};
        sheetDims    = varargin{4};
        switch pageName
            case 'Variable'
                [sheetDims, ctrlPos] = FcnCalcVariableCtrlPositions(commonGeom,dlgInfo);
            case 'Logging & Autoscaling'
                excludedCtrls = {'keepParameter'};
                if ~dlgInfo.bHeadRooms
                    excludedCtrls{end+1} = 'headroom';
                end    
                [sheetDims, ctrlPos] = ...
                    TLManageLoggingCtrls('calcCtrls', commonGeom, sheetDims, excludedCtrls);
            case 'Autoscaling'
                excludedCtrls = {'logging','keepParameter','headroom'};
                [sheetDims, ctrlPos] = ...
                    TLManageLoggingCtrls('calcCtrls', commonGeom, sheetDims, excludedCtrls);
            case 'Logging'
                excludedCtrls = {'autoscaling'};
                [sheetDims, ctrlPos] = ...
                    TLManageLoggingCtrls('calcCtrls', commonGeom, sheetDims, excludedCtrls);
            case 'RTOS'
                excludedCtrls = {};
                if ~dlgInfo.bAccessor
                    excludedCtrls{end+1} = 'accessor';
                end    
                [sheetDims, ctrlPos] = tl_manage_message_ctrls('ctrlpos', commonGeom, sheetDims, excludedCtrls);
        end
        varargout{1} = sheetDims;
        varargout{2} = ctrlPos;

    case 'Create'
        pageName = varargin{1};
        dlgfig   = varargin{2};
        dlgdata  = varargin{3};
        pageNum  = strmatch(pageName, dlgdata.pageNames, 'exact');
        switch pageName
            case 'Variable'
                dlgdata = FcnCreateVariableControls(pageNum,dlgfig,dlgdata);                 
            case {'Autoscaling','Logging & Autoscaling','Logging'}
                dlgdata = TLManageLoggingCtrls('create', pageNum, dlgfig, dlgdata);
            case 'RTOS'
                dlgdata = tl_manage_message_ctrls('create', pageNum, dlgfig, dlgdata);
        end
        dlgdata.pageData{pageNum}.ctrlPos = [];
        varargout{1} = dlgdata;

    case 'Manage',
        pageName   = varargin{1};
        dlgfig     = varargin{2};
        dlgdata    = varargin{3};
        pageAction = varargin{4};
        pageNum    = strmatch(pageName,dlgdata.pageNames,'exact');
        switch pageName
            case 'Variable'
                [dlgdata, bModified] = FcnManageVariableControls(pageNum, dlgfig, dlgdata, pageAction);
            case {'Autoscaling','Logging & Autoscaling','Logging'}
                [dlgdata, bModified] = ...
                    TLManageLoggingCtrls('manage', pageNum, dlgdata, pageAction, 'sf', 'sf');
            case 'RTOS'
                [dlgdata, bModified] = tl_manage_message_ctrls( ...
                    'manage', pageNum, dlgdata, pageAction);
        end
        varargout{1} = dlgdata;
        varargout{2} = bModified ;

    case 'ManageSystemIcons',
        dlgfig     = varargin{1};
        dlgdata    = varargin{2};
        pageAction = varargin{3};
        [dlgdata, bModified] = FcnManageSystemIcons(dlgfig,dlgdata,pageAction);
        varargout{1} = dlgdata;
        varargout{2} = bModified;

    case 'Update'
        dlgfig    = varargin{1};
        dlgdata   = varargin{2};
        pageNum   = varargin{3};

        pageName  = dlgdata.pageNames{pageNum};

        switch pageName
            case 'Variable'
               dlgdata = FcnUpdateVariableControls(dlgdata, dlgfig, pageNum);
            case {'Autoscaling','Logging & Autoscaling','Logging'}
                dlgdata = TLManageLoggingCtrls('update',pageNum,dlgdata,'sf','sf');
                TLManageLoggingCtrls('setCtrls',pageNum, dlgfig, dlgdata);
            case 'RTOS'
                dlgdata = tl_manage_message_ctrls('update',pageNum, dlgdata);
                tl_manage_message_ctrls('setCtrls', pageNum, dlgfig, dlgdata);
        end
        varargout{1} = dlgdata;

    case 'Apply'
        dlgdata  = varargin{2};
        bClose   = varargin{3};
        [dlgdata, bClose] = tl_apply_blockdata(dlgdata, bClose);
        varargout{1} = dlgdata;
        varargout{2} = bClose;

    otherwise
        error(['Invalid action "' action '"']);

end


%-----------------------------------------------------------------------------------------
% FcnCalcOutputCtrlPositions calculates positions for all controls on variable page
%
% INPUT ARGUMENTS
%   commonGeom      common geometrie information
%   dlgInfo         info about SF objects
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims, ctrlPos] = FcnCalcVariableCtrlPositions(commonGeom,dlgInfo)

excludedCtrls = {...
    'width' ...
    'samescaling'...
    'element' ...
    'scalarExp' ...
    };
if ~dlgInfo.bLimits
    excludedCtrls{end+1} = 'saturate';
end
if ~dlgInfo.bInheritance
    excludedCtrls{end+1} = 'inheritproperties';
end
if ~dlgInfo.bAddress
    excludedCtrls{end+1} = 'address';
end

[sheetDims, ctrlPos, col, colDelta, rowDelta] = ...
    tl_calc_ctrls_positions(commonGeom, excludedCtrls);

strings_and_styles = { ...
    'Constant:',            'text'; ...
    'create input variable','checkbox'};

[valLabelSize, ...
    createInputVariableCheckboxSize] = ...
    ds_get_uicontrol_sizes(commonGeom, strings_and_styles);

%-----------------------------------------------------------
% all controls lie in one row
%-----------------------------------------------------------

cy = commonGeom.frameBottomEdgeBuffer;

% constant value label
cx = col(1);

if dlgInfo.bValue
    ctrlPos.valLabel = [cx cy valLabelSize];

    % value edit field
    cx = col(2);
    ctrlPos.valEdit = [cx cy ctrlPos.lsbEdit(3:4)];
    cx = cx + colDelta / 3 + ctrlPos.valEdit(3);
end

if dlgInfo.bCreateInputVariable
    ctrlPos.createInputVariableCheckbox = [cx cy createInputVariableCheckboxSize];
end    

% increase sheet dimensions
sheetDims(2) = sheetDims(2) ...
    + ctrlPos.addoptGroupbox(4) ...
    + commonGeom.textHeight ...
    + rowDelta;


%-----------------------------------------------------------------------------------------
% FcnCreateVariableControls creates the figure window
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateVariableControls(pageNum,dlgfig,dlgdata)

% create constant controls
ctrlPos = dlgdata.pageData{pageNum}.ctrlPos;
Children = dlgdata.pageData{pageNum}.children;

if isfield(ctrlPos,'valEdit') || isfield(ctrlPos,'createInputVariableCheckbox')
    % create the addoptGroupbox which will contain further controls
    Children.addoptGroupbox = uipanel( ...
        'Parent',            dlgfig, ...
        'Title',            {'Options'}, ...
        'Units',            'pixels', ...
        'Position',          ctrlPos.addoptGroupbox);
    
    if isfield(ctrlPos,'valEdit')
        Children.valLabel = uicontrol( ...
            'Parent',             Children.addoptGroupbox, ...
            'Style',              'text', ...
            'String',             'Value:', ...
            'Position',           ctrlPos.valLabel);
        
        Children.valEdit = uicontrol( ...
            'Parent',             Children.addoptGroupbox, ...
            'BackgroundColor',    'w', ...
            'Style',              'edit', ...
            'Position',           ctrlPos.valEdit);
    end
    if isfield(ctrlPos,'createInputVariableCheckbox')
        Children.createInputVariableCheckbox = uicontrol( ...
            'Parent',             Children.addoptGroupbox, ...
            'String',             'Create input variable', ...
            'Style',              'checkbox', ...
            'Position',           ctrlPos.createInputVariableCheckbox);
    end
end

dlgdata.pageData{pageNum}.children = Children;

% create standard controls
dlgdata = TLManageVariableCtrls('create', pageNum, dlgfig, dlgdata);
dlgdata = TLManageScalingCtrls('create', pageNum, dlgfig, dlgdata);


%-----------------------------------------------------------------------------------------
% FcnManageOutputControls manages control actions of variable page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   pageAction  action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageVariableControls(pageNum, dlgfig, dlgdata, pageAction)

bModified = 0;

Children  = dlgdata.pageData{pageNum}.children;
switch pageAction
    case 'valEdit'
        valStr = tl_deblank(get(Children.valEdit, 'String'), 2);
        if ~strcmp(dlgdata.data.value,valStr)
            % empty value is allowed
            dlgdata.data.value = valStr;
            bModified = 1;
        end
    case 'createInputVariableCheckbox'
        dlgdata.data.createinputvariable = get(Children.createInputVariableCheckbox, 'Value');
        bModified = 1;
    otherwise
        [dlgdata, bModified1] = ...
            TLManageVariableCtrls('manage', pageNum, dlgfig, dlgdata, pageAction, 'sf');
        [dlgdata, bModified2] = ...
            TLManageScalingCtrls('manage', pageNum, dlgfig, dlgdata, pageAction, 'sf');
        bModified = bModified1 || bModified2;
end


%--------------------------------------------------------------------------
% FcnUpdateOutputControls updates the controls of the output tab
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%   dlgfig      figure handle of dialog
%   pageNum     page Number
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdateVariableControls(dlgdata, dlgfig, pageNum)

Children = dlgdata.pageData{pageNum}.children;

simulatedLabelCtrlStatus = struct('enable','on','string','simulated');
ctrlsList = {'simulatedLabel'};


% update variable controls
dlgdata = TLManageVariableCtrls('update', pageNum, dlgdata, 'sf');

constraint = [];
if isfield(Children,'valEdit')
    ctrlsList{end+1} = 'valEdit';
    valueEnable = 'on';
    
    % SF Parameter and EML Parameter: value is r/o
    d = tl_manage_blockset('GetDataDescription',dlgdata.maskType);
    c = tl_get_constants;
    idx = find(strcmp(d(:,1),'value'));
    if ~isempty(idx) && isequal(d{idx,2}{1,2},c.TL_READONLY)
        valueEnable = 'inactive'; 
    end    
    
    valEditCtrlStatus = struct('enable', valueEnable, 'string', dlgdata.data.value);
    [value, constraint, bCompliant] = tl_get_param_constraints(dlgdata.data, dlgdata.extdata); %#ok<ASGLU>
    if ~bCompliant
        valEditCtrlStatus.iserror = 1; %#ok<STRNU>
    end
end
if ~isfield(dlgdata.data,'loggingmode')
    simulatedLabelCtrlStatus.string = 'of value'; %#ok<STRNU>
end    


if isfield(Children,'createInputVariableCheckbox')
    ctrlsList{end+1} = 'createInputVariableCheckbox';
    createInputVariableCheckboxCtrlStatus  = struct('enable', 'on', 'value', dlgdata.data.createinputvariable); %#ok<NASGU>
end    

dlgdata = TLManageScalingCtrls('update', pageNum, dlgdata, 'sf', constraint);


% write control status of extra controls to the control
for ctrlsNo = 1:length(ctrlsList)
    ctrl = Children.(ctrlsList{ctrlsNo});
    UserData = get(ctrl, 'UserData');
    UserData.ctrlStatus = eval([ctrlsList{ctrlsNo} 'CtrlStatus']);
    set(ctrl, 'UserData', UserData);
end

% set standard controls
TLManageVariableCtrls('setCtrls', pageNum, dlgfig, dlgdata);
TLManageScalingCtrls('setCtrls', pageNum, dlgfig, dlgdata);

% set non-standard controls
TLSetCtrlsStatus(dlgfig, Children, ctrlsList);


%-----------------------------------------------------------------------------------------
% FcnManageSystemIcons manage actions of toolbar icons
%
% INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   action      action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageSystemIcons(dlgfig, dlgdata, action) %#ok

bModified = false;
sfPath = tl_pathinfo(dlgdata.model);
hChart = get_param(sfPath.path, 'Handle');

switch action
    case 'EditCode'
        % look for associated production code file
        [codefile,blockstr] = get_codefile(hChart, 'sfobject', dlgdata.model);
        if ~isempty(codefile)
            codeedit(codefile,blockstr);
        end
        
    case 'ViewCode'
        tl_create_links_to_model('ShowComputation', hChart);
        
    otherwise
        error('Invalid callback');

end % switch(action)

